/*
      协作式系统框架 V1.3
      2021年02月26日

  简述：
非抢占式，轮询非阻塞任务
可裁剪：运行统计、任务优先级、简单抢占式、系统时钟功能

*/

#ifndef _TEAM_OS_FRAME_H
#define _TEAM_OS_FRAME_H

/*-----------------------功能选项----------------------------------------------*/
#define TASK_STRING_MAX 200u //任务名字符串数组尺寸

#define USETOSF_INFO_FUNC 0     //统计功能
#define USETOSF_TASK_PRIORITY 0 /* 任务优先级，使能后具有抢占或优先执行功能； 高于TOSF_SEIZE_PRIORITY则具有抢占功能；慎用，霸权问题*/
#define USETOSF_SYSTIME_INFO 1  //系统时钟功能 ：系统启动时间（ms）、函数执行时间（us）

#define TOSF_SEIZE_PRIORITY 100u //任务抢占优先级，从此优先级开始可单次抢占，优先级7bit-127

/*-------------------------类型定义----------------------*/
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;

typedef unsigned char type_TaskId; //任务ID，用于手动修改运行状态等

/*-----------系统时钟功能--------------*/
#if USETOSF_SYSTIME_INFO

extern volatile u32 TOSF_SysTimeValue;
#define TOSF_GetSysTime() (TOSF_SysTimeValue - 0) //使用宏定义传入接收指针获取系统时钟，单位ms

#endif

/*-------------任务信息结构体--------------*/
typedef struct
{
    volatile u8 state;    //运行状态及优先级 bit7：1运行 0不运行 bit0-6：优先级（0-max）
    u16 timer;            //计时器:累加时间至period
    u16 period;           //任务调用周期，单位ms
    u16 period_bk;        //备份,用于任务延时等
    void (*func_p)(void); //任务函数

/*-------------优先级功能-------------*/
#if USETOSF_TASK_PRIORITY
    u8 next_index; //链表索引
#endif

/*-------------统计功能-------------*/
#if USETOSF_INFO_FUNC
    u32 run_total_time; //任务运行累计总时间
    u32 run_max_time;   //任务运行最大耗时
    u16 run_count;      //运行次数统计
    char *task_name_p;  //任务名字字符指针
#endif

} type_TOSF_Task;

/*-------------------API----------------------------------------------*/

/**
 * 初始化全部变量
 * 初始化管理结构体，绑定任务数组
 * @param 1:任务数组，用以记录任务信息
 * @param 2:任务数组最大尺寸
 */
void TOSF_Init(type_TOSF_Task *task_tab, u8 tab_max);

/**
 * 注册任务
 * @param ： 1-4
 * @return ：任务注册成功ID，0-250=任务ID，0xff=超过最大注册数量 0xfe=任务函数错误
 * @note :周期=0时轮询（此时需注意开启优先级后霸权问题）
 */
type_TaskId TOSF_LoginTask(void (*func_p)(void), u16 period, u8 priority, char *name_p);

/**
 * 运行任务
 * 轮询，查询标志位后运行任务
 */
void TOSF_TaskHandler(void);

/**
 * 定时回调
 * 获取任务调度节拍
 * 任务运行态判断与切换
 * @param 1: 节拍ms数
 */
void TOSF_TimerCB(u8 _ms);

/**
 * 指定时间任务运行一次
 * 延时一段时间运行（ms），=0时立刻运行
 * 运行完后自动恢复之前状态
 * 只运行一次，使用备份周期实现
 * @param 1:任务ID
 * @param 2:延时时间ms
 */
void TOSF_TaskRunOnce(type_TaskId id, u16 time);

/**
 * 设置任务周期
 */
void TOSF_SetTaskPeriod(type_TaskId id, u16 ms);

#if USETOSF_TASK_PRIORITY
/**
 * 任务抢占
 * 抢占式任务调度，中断函数中调用，用于高优先级任务抢占
 * 默认在定时回调函数中使用，可单独添加在其他中断中实现嵌套
 * 注意：高优先级任务必须保证执行时间短
 */
void TOSF_TaskSeize(void);
#endif

/**
 * 函数执行时间测量
 * 依赖TimeCB()中ms计时变量、us获取函数
 * 注意：函数不可重入，不能在中断中使用（依赖定时中断）
 * @param 1: 无参数无返回值函数指针
 * @param 2：执行时间，单位us
 */
u32 TOSF_ExeTime(void (*func)(void));

/* -------------虚函数声明-------------- */
/**
 * 获取当前系统us值
 * 需要外部重构，默认无功能，最大获取us值为999（%1000)
 * STM32F103 示例
 * @param 1:接收指针
 */
extern u32 TOSF_GetSysTime_us(void);

/**
 * 空闲任务
 * 默认打印统计信息
 * 注意：需要满足运行时间低于1ms
 */
extern void TOSF_IdleTask(void);

/*-------------------API_End----------------------------------------------*/
#endif

/* -------------Demo------------- */
#if 0

/* Demo */

#include "TeamOSFrame.h"
int main(void)
{
    /* 创建内存并初始化 */
    static type_TOSF_Task task_tab[5];
    TOSF_Init(task_tab, sizeof(task_tab) / sizeof(type_TOSF_Task));

    /* 外设初始化 */
    Init();

    /* 注册任务：任务函数、周期、优先级、任务名（可空字符串）；注册后返回任务ID号 */
    type_TaskId ID_Tim1s = TOSF_LoginTask(task_timing_1s, 1000, 0, "T_1S");
    TOSF_LoginTask(task_feed_iwdg, 3000, 50, "IWDG");

    while (1)
    {
        /* 非阻塞轮询调度 */
        TOSF_TaskHandler();
    }
}

/* 定时器中断中调用，传入定时器中断时间（节拍） */
#include "TeamOSFrame.h"
void TIM2_IRQHandler(void)
{
    TOSF_TimerCB(1);
}
#endif
